package com.cencat.user.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 用户角色关联创建DTO
 * @author cencat
 * @since 2024-01-01
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "用户角色关联创建DTO")
public class UserRoleCreateDTO {

    /**
     * 用户ID
     */
    @NotNull(message = "用户ID不能为空")
    @Min(value = 1, message = "用户ID必须大于0")
    @Schema(description = "用户ID", example = "1")
    private Long userId;

    /**
     * 角色ID
     */
    @NotNull(message = "角色ID不能为空")
    @Min(value = 1, message = "角色ID必须大于0")
    @Schema(description = "角色ID", example = "1")
    private Long roleId;

    /**
     * 角色ID列表（批量分配时使用）
     */
    @Schema(description = "角色ID列表（批量分配）")
    private List<Long> roleIds;

    /**
     * 用户ID列表（批量分配时使用）
     */
    @Schema(description = "用户ID列表（批量分配）")
    private List<Long> userIds;

    /**
     * 分配人ID
     */
    @Schema(description = "分配人ID", example = "1")
    private Long assignBy;

    /**
     * 分配人姓名
     */
    @Size(max = 50, message = "分配人姓名长度不能超过50个字符")
    @Schema(description = "分配人姓名", example = "管理员")
    private String assignByName;

    /**
     * 有效期开始时间
     */
    @Schema(description = "有效期开始时间", example = "2024-01-01T00:00:00")
    private LocalDateTime validFrom;

    /**
     * 有效期结束时间
     */
    @Schema(description = "有效期结束时间", example = "2024-12-31T23:59:59")
    private LocalDateTime validTo;

    /**
     * 状态（true-启用，false-禁用）
     */
    @Schema(description = "状态（true-启用，false-禁用）", example = "true")
    private Boolean status = true;

    /**
     * 备注
     */
    @Size(max = 500, message = "备注长度不能超过500个字符")
    @Schema(description = "备注", example = "系统管理员角色")
    private String remark;

    /**
     * 租户ID
     */
    @Schema(description = "租户ID", example = "1")
    private Long tenantId;

    /**
     * 是否立即生效
     */
    @Schema(description = "是否立即生效", example = "true")
    private Boolean immediateEffect = true;

    /**
     * 有效期天数（用于快速设置有效期）
     */
    @Min(value = 1, message = "有效期天数必须大于0")
    @Max(value = 3650, message = "有效期天数不能超过3650天")
    @Schema(description = "有效期天数", example = "365")
    private Integer validDays;

    /**
     * 是否发送通知
     */
    @Schema(description = "是否发送通知", example = "true")
    private Boolean sendNotification = false;

    /**
     * 通知方式（email, sms, system）
     */
    @Schema(description = "通知方式", example = "email")
    private String notificationMethod;

    // 构造函数
    public UserRoleCreateDTO(Long userId, Long roleId) {
        this.userId = userId;
        this.roleId = roleId;
        this.status = true;
        this.immediateEffect = true;
        this.sendNotification = false;
    }

    public UserRoleCreateDTO(Long userId, Long roleId, Long assignBy, String assignByName) {
        this(userId, roleId);
        this.assignBy = assignBy;
        this.assignByName = assignByName;
    }

    public UserRoleCreateDTO(Long userId, List<Long> roleIds) {
        this.userId = userId;
        this.roleIds = roleIds;
        this.status = true;
        this.immediateEffect = true;
        this.sendNotification = false;
    }

    // 业务方法

    /**
     * 校验有效期设置
     * @return 校验结果
     */
    public boolean isValidPeriodValid() {
        if (validFrom == null && validTo == null) {
            return true; // 无限期有效
        }
        
        if (validFrom != null && validTo != null) {
            return validFrom.isBefore(validTo);
        }
        
        return true;
    }

    /**
     * 校验批量分配参数
     * @return 校验结果
     */
    public boolean isBatchAssignValid() {
        // 单个用户分配多个角色
        if (userId != null && roleIds != null && !roleIds.isEmpty()) {
            return roleId == null;
        }
        
        // 多个用户分配单个角色
        if (roleId != null && userIds != null && !userIds.isEmpty()) {
            return userId == null;
        }
        
        // 单个用户分配单个角色
        if (userId != null && roleId != null) {
            return (roleIds == null || roleIds.isEmpty()) && 
                   (userIds == null || userIds.isEmpty());
        }
        
        return false;
    }

    /**
     * 获取实际的有效期开始时间
     * @return 有效期开始时间
     */
    public LocalDateTime getActualValidFrom() {
        if (immediateEffect != null && immediateEffect) {
            return LocalDateTime.now();
        }
        return validFrom;
    }

    /**
     * 获取实际的有效期结束时间
     * @return 有效期结束时间
     */
    public LocalDateTime getActualValidTo() {
        if (validDays != null && validDays > 0) {
            LocalDateTime startTime = getActualValidFrom();
            if (startTime != null) {
                return startTime.plusDays(validDays);
            } else {
                return LocalDateTime.now().plusDays(validDays);
            }
        }
        return validTo;
    }

    /**
     * 检查是否需要发送通知
     * @return 是否需要发送通知
     */
    public boolean shouldSendNotification() {
        return sendNotification != null && sendNotification && 
               notificationMethod != null && !notificationMethod.trim().isEmpty();
    }

    /**
     * 获取分配的角色数量
     * @return 角色数量
     */
    public int getRoleCount() {
        if (roleIds != null && !roleIds.isEmpty()) {
            return roleIds.size();
        }
        return roleId != null ? 1 : 0;
    }

    /**
     * 获取分配的用户数量
     * @return 用户数量
     */
    public int getUserCount() {
        if (userIds != null && !userIds.isEmpty()) {
            return userIds.size();
        }
        return userId != null ? 1 : 0;
    }

    /**
     * 检查是否为批量分配
     * @return 是否为批量分配
     */
    public boolean isBatchAssign() {
        return (roleIds != null && roleIds.size() > 1) || 
               (userIds != null && userIds.size() > 1);
    }

    /**
     * 获取所有需要分配的角色ID
     * @return 角色ID列表
     */
    public List<Long> getAllRoleIds() {
        if (roleIds != null && !roleIds.isEmpty()) {
            return roleIds;
        }
        if (roleId != null) {
            return List.of(roleId);
        }
        return List.of();
    }

    /**
     * 获取所有需要分配的用户ID
     * @return 用户ID列表
     */
    public List<Long> getAllUserIds() {
        if (userIds != null && !userIds.isEmpty()) {
            return userIds;
        }
        if (userId != null) {
            return List.of(userId);
        }
        return List.of();
    }

    /**
     * 设置快速有效期（从现在开始的指定天数）
     * @param days 天数
     */
    public void setQuickValidPeriod(int days) {
        this.validDays = days;
        this.immediateEffect = true;
        this.validFrom = null;
        this.validTo = null;
    }

    /**
     * 设置永久有效
     */
    public void setPermanentValid() {
        this.validFrom = null;
        this.validTo = null;
        this.validDays = null;
        this.immediateEffect = true;
    }

    /**
     * 设置自定义有效期
     * @param validFrom 开始时间
     * @param validTo 结束时间
     */
    public void setCustomValidPeriod(LocalDateTime validFrom, LocalDateTime validTo) {
        this.validFrom = validFrom;
        this.validTo = validTo;
        this.validDays = null;
        this.immediateEffect = false;
    }

    /**
     * 启用通知
     * @param method 通知方式
     */
    public void enableNotification(String method) {
        this.sendNotification = true;
        this.notificationMethod = method;
    }

    /**
     * 禁用通知
     */
    public void disableNotification() {
        this.sendNotification = false;
        this.notificationMethod = null;
    }

    /**
     * 校验通知方式
     * @return 校验结果
     */
    public boolean isNotificationMethodValid() {
        if (!shouldSendNotification()) {
            return true;
        }
        
        String method = notificationMethod.toLowerCase();
        return "email".equals(method) || "sms".equals(method) || "system".equals(method);
    }

    /**
     * 获取分配描述
     * @return 分配描述
     */
    public String getAssignDescription() {
        int userCount = getUserCount();
        int roleCount = getRoleCount();
        
        if (userCount == 1 && roleCount == 1) {
            return "单用户单角色分配";
        } else if (userCount == 1 && roleCount > 1) {
            return "单用户多角色分配";
        } else if (userCount > 1 && roleCount == 1) {
            return "多用户单角色分配";
        } else {
            return "批量分配";
        }
    }

    /**
     * 转换为字符串表示
     * @return 字符串表示
     */
    @Override
    public String toString() {
        return "UserRoleCreateDTO{" +
                "userId=" + userId +
                ", roleId=" + roleId +
                ", roleIds=" + roleIds +
                ", userIds=" + userIds +
                ", assignBy=" + assignBy +
                ", assignByName='" + assignByName + '\'' +
                ", validFrom=" + validFrom +
                ", validTo=" + validTo +
                ", status=" + status +
                ", immediateEffect=" + immediateEffect +
                ", validDays=" + validDays +
                '}';
    }
}